home *** CD-ROM | disk | FTP | other *** search
/ MIDICraft's MIDINET CD-ROM / MIDICraft's MIDINET CD-ROM.iso / DOSUTILS / MIDIFIND.ZIP / MIDIFIND.CPP next >
Encoding:
C/C++ Source or Header  |  1997-03-09  |  6.6 KB  |  373 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4.  
  5. #ifdef __MSDOS__
  6. #include <mem.h>
  7. #define WRITE_BINARY  "wb"
  8. #define READ_BINARY   "rb"
  9. #ifdef GNDIR
  10. #include "gndir.h"
  11. #endif
  12. #else
  13. #define WRITE_BINARY  "w"
  14. #define READ_BINARY   "r"
  15. #endif
  16.  
  17. #define SEARCHBUFSIZE  0xa000U  // 40K is average midi file size
  18.  
  19. char trivialcheck = 0;
  20.  
  21. int findchar(unsigned char* s, unsigned slen, char c)
  22. {
  23.   if (memchr(s, c, slen))
  24.     return 1;
  25.   if (!isalpha(c))
  26.     return 0;
  27.   if (c >= 'a' && c <= 'z')
  28.     return memchr(s, toupper(c), slen) != 0;
  29.   return memchr(s, tolower(c), slen) != 0;
  30. }
  31.  
  32. int matching(unsigned char* s, char* w, unsigned slen)
  33. {
  34.   while (*w)
  35.   {
  36.     if (*s == 0)
  37.     {
  38.       if (*w == '*')
  39.       {
  40.     w++;
  41.     continue;
  42.       }
  43.       return 0;
  44.     }
  45.     else if (toupper(*w) == toupper(*s))
  46.     {
  47.       w++;
  48.       s++;
  49.       slen--;
  50.     }
  51.     else if (*w == '#')
  52.     {
  53.       if (*s == 0)
  54.     return 0;
  55.       if (isdigit(*s))
  56.       {
  57.     s++;
  58.     slen--;
  59.     w++;
  60.       }
  61.       else
  62.     return 0;
  63.     }
  64.     else if (*w == '?')
  65.     {
  66.       if (*s == 0)
  67.     return 0;
  68.       s++;
  69.       slen--;
  70.       w++;
  71.     }
  72.     else if (*w == '*')
  73.     {
  74.       while (*w == '*')
  75.      w++;
  76.       if (*w == 0)
  77.     return 1;
  78. #ifdef SEEK_CHARACTERS
  79.       char* p;
  80.       for (p = w; *p; p++)
  81.       if (strchr("*?#", *p) == 0)
  82.       {
  83.     if (!findchar(s, slen, *p))
  84.       return 0;
  85.       }
  86. #endif
  87.       while (*w)
  88.       {
  89.     if (matching(s, w, slen))
  90.       return 1;
  91.     if (slen == 0 || *s == 0)
  92.       break;
  93.     s++;
  94.     slen--;
  95.       }
  96.       break;
  97.     }
  98.     else
  99.       return 0;
  100.   }
  101.   if (*w != 0)
  102.     return 0;
  103.   if (slen != 0 && *s != 0)
  104.     return 0;
  105.   return 1;
  106. }
  107.  
  108. char curfilename[128] = "";
  109.  
  110. char* trivial[] =
  111. {
  112.   "ACOU*PIANO",
  113.   "BASS",
  114.   "BASOON",
  115.   "BELL*",
  116.   "BRASS",
  117.   "CYMBAL*",
  118.   "*DRUM*",
  119.   "CELLO",
  120.   "CHOIR",
  121.   "CLARINET",
  122.   "CONTRABASS",
  123.   "E*GUITAR",
  124.   "E*PIANO",
  125.   "FL?CHE",
  126.   "FLUTE",
  127.   "FRENCH*HORN",
  128.   "FUNKYGIT",
  129.   "GITARRE",
  130.   "GLOCKENSPIEL",
  131.   "GUITAR",
  132.   "HIHAT",
  133.   "HI?HAT",
  134.   "JAZZ*GUITAR",
  135.   "MELODIE",
  136.   "MELODY",
  137.   "MIDI",
  138.   "MUTE*G*TAR*",
  139.   "ORCH*HIT",
  140.   "*ORGAN",
  141.   "*ORGEL",
  142.   "PERCUSSION",
  143.   "PIANO",
  144.   "PIANO*LEFT",
  145.   "PIANO*RIGHT",
  146.   "PIZZICATO",
  147.   "POLYSYNTH",
  148.   "SANTUR",
  149.   "SAX",
  150.   "SLOW*STR*",
  151.   "SNARE",
  152.   "SOLO*G*TAR*",
  153.   "STRINGS",
  154.   "SYNTH*B*ASS",
  155.   "TIMPANI",
  156.   "TOMS",
  157.   "TRACK",
  158.   "TROMBONE*",
  159.   "TRUMPET*",
  160.   "TUBA",
  161.   "VIOLIN*",
  162.   "VOCAL*",
  163.   "VOICE*",
  164.   NULL
  165. };
  166.  
  167. int trivialtext(unsigned char* s, unsigned len)
  168. {
  169. static unsigned char buf[256];
  170. int i;
  171.  
  172.   while (len > 0 && !isalpha(*s))
  173.   {
  174.     s++; len--;
  175.   }
  176.   if (len >= sizeof(buf))
  177.     return 0;
  178.   for (i = 0; i < len; i++)
  179.   {
  180.     if (isalpha(s[i]))
  181.       buf[i] = s[i];
  182.     else
  183.       buf[i] = ' ';
  184.   }
  185.   while (len > 0 && !isalpha(buf[len-1]))
  186.     buf[--len]= 0;
  187.  
  188.   if (len == 0)
  189.     return 0;
  190.  
  191.   for (char**t = trivial; *t; t++)
  192.   if (matching(buf, *t, len))
  193.     return 1;
  194.   return 0;
  195. }
  196.  
  197. void findstr(unsigned char* s, unsigned len, char* search, int searchlen)
  198. {
  199. static char subsearch[256];
  200.  
  201.   subsearch[0] = '*';
  202.   strcpy(subsearch+1, search);
  203.   strcat(subsearch, "*");
  204.  
  205.   if (matching(s, subsearch, len))
  206.   {
  207.     if (!trivialcheck || !trivialtext(s, len))
  208.     {
  209.     const char* longname;
  210.  
  211. #if defined(__MSDOS__) && defined(GNDIR)
  212.       longname = getlongfilename(curfilename);
  213.       if (!longname)
  214.     longname = curfilename;
  215. #else
  216.     longname = curfilename;
  217. #endif
  218.       printf("%s: %*.*s\n", longname, len, len, s);
  219.     }
  220.   }
  221. }
  222.  
  223. // meta = 0xff [1-15] len char[len]
  224. int findmeta(unsigned char* s, unsigned len, char* search, int searchlen)
  225. {
  226.   while (len > 0)
  227.   {
  228.     unsigned char* ff = (unsigned char*)memchr(s, 0xff, len);
  229.     if (!ff)
  230.       break;
  231.     ff++;
  232.     len -= unsigned(ff - s);
  233.     s = ff;
  234.     if (len > 0 && *s <= 15 && *s >= 1 && s[1] < 0x80)
  235.     {
  236.       // s[0] == 1-15  s[1] == len s[2..] == text
  237.       if (len < s[1] + 2)
  238.     return len + 1;
  239.       findstr(s+2, s[1], search, searchlen);
  240.     }
  241.   }
  242.   return 0;
  243. }
  244.  
  245. void findfile(FILE* f, long filesize, char* search, int searchlen)
  246. {
  247. static unsigned char buf[SEARCHBUFSIZE];
  248. unsigned buflen = 0;
  249.  
  250.   while (1)
  251.   {
  252. //    memset(buf+buflen, 0, sizeof(buf)-buflen);
  253.     unsigned n = sizeof(buf) - buflen;
  254.     if (filesize - ftell(f) < n)
  255.       n = (unsigned)(filesize-ftell(f));
  256.     if (fread(buf + buflen, n, 1, f) != 1)
  257.       break;
  258.     buflen += n;
  259.     n = findmeta(buf, buflen, search, searchlen);
  260.     if (n > 0)
  261.     {
  262.       memmove(buf, buf + buflen - n, n);
  263.       buflen = n;
  264.     }
  265.     else
  266.       buflen = 0;
  267.   }
  268. }
  269.  
  270. void findfile(char* filename, char* search, int searchlen)
  271. {
  272. FILE* f;
  273.  
  274.   f = fopen(filename, READ_BINARY);
  275.   if (!f)
  276.   {
  277.     perror(filename);
  278.     return;
  279.   }
  280.   fseek(f, 0, SEEK_END);
  281.   long filesize = ftell(f);
  282.   rewind(f);
  283.  
  284. //  puts(filename);
  285. //  puts(search);
  286.   strcpy(curfilename, filename);
  287.   findfile(f, filesize, search, searchlen);
  288.   fclose(f);
  289. }
  290.  
  291. #ifdef __MSDOS__
  292. // get filenames containing wildcards *, ?
  293. #include <dir.h>
  294. #include <dos.h>
  295. void findlist(char* filelist, char* search, int searchlen)
  296. {
  297.   if (strchr(filelist, '*') == 0 && strchr(filelist, '?') == 0)
  298.     findfile(filelist, search, searchlen);
  299.   else
  300.   {
  301.   struct ffblk dir;
  302.   int done = findfirst(filelist, &dir, FA_RDONLY+FA_ARCH);
  303.  
  304.   char fullname[128], *p;
  305.  
  306.     p = strrchr(filelist, '\\');
  307.     if (!p)
  308.       p = strchr(filelist, ':');
  309.     if (p)
  310.     {
  311.       strncpy(fullname, filelist, p - filelist+1);
  312.       p = fullname + (p-filelist)+1;
  313.     }
  314.     else
  315.       p = fullname;
  316.     while (!done)
  317.     {
  318.       if ((dir.ff_attrib & (FA_DIREC+FA_HIDDEN+FA_LABEL+FA_SYSTEM)) == 0)
  319.       {
  320.     strcpy(p, dir.ff_name);
  321.     findfile(fullname, search, searchlen);
  322.       }
  323.       done = findnext(&dir);
  324.     }
  325.   }
  326. }
  327. #endif
  328.  
  329. void usage()
  330. {
  331.   fprintf(stderr, "midifind search files.mid ...\n");
  332.   return;
  333. }
  334.  
  335. void main(int argc, char** argv)
  336. {
  337. char* name;
  338.  
  339.   argc--; argv++;
  340.   while (argc > 0 && **argv == '-')
  341.   {
  342.     if (strncmp(*argv, "-trivial", 2) == 0)
  343.     {
  344.       trivialcheck = 1;
  345.       argc--; argv++; continue;
  346.     }
  347.     fprintf(stderr, "invalid option: %s\n", *argv);
  348.     argc--; argv++;
  349.   }
  350.   if (!argc)
  351.     usage();
  352.  
  353.   char * search = *argv++; argc--;
  354.  
  355. #ifdef __MSDOS__
  356.   if (!argc)
  357.     findlist("*.mid", search, strlen(search));
  358. #else
  359.   if (!argc)
  360.     usage();
  361. #endif
  362.  
  363.   while (argc-- > 0)
  364.   {
  365.     name = *argv++;
  366. #ifdef __MSDOS__
  367.     findlist(name, search, strlen(search));
  368. #else
  369.     findfile(name, search, strlen(search));
  370. #endif
  371.   }
  372. }
  373.